package services.application;

import java.util.*;

import controllers.BaseController;
import models.pubobj.AniObjectState;
import models.pubobj.AniObjectType;
import models.user.*;
import services.exception.AniAuthException;
import services.exception.AniDataException;
import services.exception.AniRuleException;
import utils.*;

import models.application.*;

public class AniAppService extends BaseController {

    public static AniApp getApp(AniApp oneApp){
        AniApp retApp = getAppWithEntity(oneApp);
        if(retApp == null){
            throw new AniDataException("APP_NOT_EXISTS");
        }
        return retApp;
    }
    public static void checkAppForwardUrlLegality(AniApp oneApp){
        if(!AniPatternUtils.isMatches(oneApp.forwardUrl, AniPatternUtils.URL_PATTERN)){
            throw new AniRuleException("API_URL_ILLEGAL");
        }
    }
    public static void checkAppNotExistence(AniApp oneApp){
        if(getAppWithEntity(oneApp) != null){
            throw new AniDataException("DUPLICATE_APP_NAMES_OR_ID");
        }
    }
    public static void checkAppExistence(AniApp oneApp){
        if(oneApp == null || oneApp.id == null || AniApp.findByAppId(oneApp.id) == null){
            throw new AniDataException("APP_NOT_EXISTS");
        }
    }
    public static void checkAppsExistenceWithIds(List<Long> appsId){
        Integer existAppCount = AniApp.findAppsCountWithId(appsId);
        if(existAppCount < 1 || existAppCount < appsId.size()){
            throw new AniDataException("AT_LEAST_ONE_APP_NOT_EXISTS");
        }
    }
    public static void checkAppsPrivacyWithIds(List<Long> appsId, AniObjectState curState){
        if(AniApp.findByStateCount(appsId, curState) != appsId.size()){
            throw new AniAuthException("APP_STATE_NOT_AVAILABLE");
        }
    }
    private static AniApp getAppWithId(Long id){
        return AniApp.findByAppId(id);
    }
    private static AniApp getAppWithName(String appName){
        return AniApp.findByAppName(appName);
    }
    private static AniApp getAppWithEntity(AniApp oneApp){
        if(oneApp.id != null){
            return getAppWithId(oneApp.id);
        }else if(oneApp.appName != null){
            return getAppWithName(oneApp.appName);
        }else{
            return null;
        }
    }
	public static Map<Integer, String> getAppClassificationNames(){
		List<AniAppClassification> aniAppClassifications = AniAppClassification.findAll();
		Map<Integer, String> classifications = new HashMap<Integer, String>();
		if(AniGeneralUtils.isListEmpty(aniAppClassifications)){
			return null;
		}
		for(AniAppClassification oneClass: aniAppClassifications){
			classifications.put(oneClass.id.intValue(), oneClass.classificationKey);
		}
		return classifications;
	}
    public static AniAppClassification getAppClassificationWithId(Long classificationId){
        return AniAppClassification.getById(classificationId);
    }
	
	public static Map<Integer, String> getUserAppNames(String userEmail){
		List<AniApp> userApps = AniApp.findByOwnerEmail(userEmail);
		Map<Integer, String> apps = new HashMap<Integer, String>();
		if(AniGeneralUtils.isListEmpty(userApps)){
			return null;
		}
		for(AniApp oneApp: userApps){
			apps.put(oneApp.id.intValue(), oneApp.appName);
		}
		return apps;
	}
    public static void checkAppOwner(AniUser oneUser, AniApp oneApp){
        if(oneApp.ownerUser.id != oneUser.id){
            throw new AniAuthException("CURRENT_USER_IS_NOT_OWNER_OF_THIS_APP");
        }
    }
    public static void checkRelyOnAppPrivacy(AniUser oneUser, AniApp relationApp){
        if(relationApp != null
                && relationApp.ownerUser.id != oneUser.id){
            throw new AniAuthException("RELY_ON_APP_PRIVACY_ILLEGAL");
        }
    }
    public static void checkAppsHaveSameOwnership(AniApp[] apps){
        if(apps.length == 0){
            throw new AniRuleException("NO_APP_ENTRANCED");
        }
        Long oneAppOwnerId = apps[0].ownerUser.id;
        for(AniApp oneApp: apps){
            if(oneApp.id != oneAppOwnerId){
                throw new AniDataException("APPS_OWNER_NOT_SAME");
            }
        }
    }
}
